/*
 * Copyright 2014-2025 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.netflix.atlas.eval.util

import java.util.regex.Pattern

import com.netflix.atlas.core.model.Query
import com.netflix.atlas.core.model.StyleExpr
import com.typesafe.config.Config

/**
  * Utility for rewriting an Atlas query expression based on the host used. This is useful
  * for cases where the same backend is serving requests, but there might be multiple DNS
  * names used that are intended to provide specific views.
  *
  * Sample config:
  *
  * ```
  * pattern = "&#94;foo\\.([&#94;.]+)\\.example\\.com$"
  * key = "region"
  * ```
  *
  * This config would extract the second portion of the host name and use it as a region
  * restriction (`region,\$1,:eq`). The first group will be used as the value for the restriction
  * query.
  */
class HostRewriter(config: Config) {

  private val pattern = Pattern.compile(config.getString("pattern"))
  private val key = config.getString("key")

  def rewrite(host: String, inputExprs: List[StyleExpr]): List[StyleExpr] = {
    val matcher = pattern.matcher(host)
    if (matcher.matches()) {
      val value = matcher.group(1)
      val restrictionQuery = Query.Equal(key, value)
      inputExprs.map(e => rewrite(restrictionQuery, e))
    } else {
      inputExprs
    }
  }

  private def rewrite(restrictionQuery: Query, styleExpr: StyleExpr): StyleExpr = {
    val newExpr = styleExpr.rewrite {
      case q: Query => Query.And(q, restrictionQuery)
    }
    newExpr.asInstanceOf[StyleExpr]
  }
}
